package com.chushouya.order.dao.repository;

import com.general.framework.core.lang.Lists;
import com.general.framework.core.lang.Strings;
import com.general.framework.core.schema.PageResult;
import com.general.framework.data.mybatis.BaseRepository;
import com.chushouya.order.dao.entity.PaymentLogEntity;
import com.chushouya.order.dao.mapper.PaymentLogEntityMapper;
import com.chushouya.order.dto.admin.paymentlog.PaymentLogQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Objects;

/**
 * 支付日志Repository
 */
@Repository
@Slf4j
public class PaymentLogRepository extends BaseRepository<PaymentLogEntityMapper, PaymentLogEntity, Long> {

    public PaymentLogEntity selectOne(PaymentLogQuery query) {
        return this.selectFirstOneByExample(this.buildExample(query));
    }

    public PageResult<PaymentLogEntity> selectPageResult(PaymentLogQuery query) {
        final Example example = this.buildExample(query);
        example.orderBy("logId").desc();
        return selectPage(query.getPageRequest(), example);
    }

    public List<PaymentLogEntity> selectList(PaymentLogQuery query) {
        return this.selectByExample(this.buildExample(query));
    }

    public Integer selectCount(PaymentLogQuery query) {
        return this.selectCountByExample(this.buildExample(query));
    }

    /**
     * 根据订单ID查询支付日志
     */
    public List<PaymentLogEntity> selectByOrderId(Long orderId) {
        Example example = buildExample();
        example.and().andEqualTo("orderId", orderId);
        example.orderBy("createTime").desc();
        return selectByExample(example);
    }

    /**
     * 根据订单号查询支付日志
     */
    public List<PaymentLogEntity> selectByOrderNo(String orderNo) {
        if (Strings.isBlank(orderNo)) {
            return Lists.newArrayList();
        }
        Example example = buildExample();
        example.and().andEqualTo("orderNo", orderNo);
        example.orderBy("createTime").desc();
        return selectByExample(example);
    }

    /**
     * 根据商户转账单号查询支付日志
     */
    public PaymentLogEntity selectByOutBizNo(String outBizNo) {
        if (Strings.isBlank(outBizNo)) {
            return null;
        }
        Example example = buildExample();
        example.and().andEqualTo("outBizNo", outBizNo);
        return selectFirstOneByExample(example);
    }

    /**
     * 根据支付宝转账单号查询支付日志
     */
    public PaymentLogEntity selectByTradeNo(String tradeNo) {
        if (Strings.isBlank(tradeNo)) {
            return null;
        }
        Example example = buildExample();
        example.and().andEqualTo("tradeNo", tradeNo);
        return selectFirstOneByExample(example);
    }

    /**
     * 根据支付状态查询支付日志
     */
    public List<PaymentLogEntity> selectByStatus(Boolean status) {
        Example example = buildExample();
        example.and().andEqualTo("status", status);
        example.orderBy("createTime").desc();
        return selectByExample(example);
    }

    /**
     * 根据支付渠道查询支付日志
     */
    public List<PaymentLogEntity> selectByPayChannel(String payChannel) {
        if (Strings.isBlank(payChannel)) {
            return Lists.newArrayList();
        }
        Example example = buildExample();
        example.and().andEqualTo("payChannel", payChannel);
        example.orderBy("createTime").desc();
        return selectByExample(example);
    }

    private Example buildExample(PaymentLogQuery query) {
        Example example = this.buildExample();
        
        if (Objects.nonNull(query.getLogId())) {
            example.and().andEqualTo("logId", query.getLogId());
        }
        if (Objects.nonNull(query.getOrderId())) {
            example.and().andEqualTo("orderId", query.getOrderId());
        }
        if (Lists.isNotEmpty(query.getOrderIdList())) {
            example.and().andIn("orderId", query.getOrderIdList());
        }
        if (Strings.isNotEmpty(query.getOrderNo())) {
            example.and().andEqualTo("orderNo", query.getOrderNo());
        }
        if (Strings.isNotEmpty(query.getOutBizNo())) {
            example.and().andEqualTo("outBizNo", query.getOutBizNo());
        }
        if (Strings.isNotEmpty(query.getTradeNo())) {
            example.and().andEqualTo("tradeNo", query.getTradeNo());
        }
        if (Strings.isNotEmpty(query.getPayChannel())) {
            example.and().andEqualTo("payChannel", query.getPayChannel());
        }
        if (Lists.isNotEmpty(query.getPayChannelList())) {
            example.and().andIn("payChannel", query.getPayChannelList());
        }
        if (Strings.isNotEmpty(query.getPayType())) {
            example.and().andEqualTo("payType", query.getPayType());
        }
        if (Lists.isNotEmpty(query.getPayTypeList())) {
            example.and().andIn("payType", query.getPayTypeList());
        }
        if (Objects.nonNull(query.getStatus())) {
            example.and().andEqualTo("status", query.getStatus());
        }
        if (Lists.isNotEmpty(query.getStatusList())) {
            example.and().andIn("status", query.getStatusList());
        }
        if (Strings.isNotEmpty(query.getOpenId())) {
            example.and().andEqualTo("openId", query.getOpenId());
        }
        if (Objects.nonNull(query.getPayAmountMin()) && Objects.nonNull(query.getPayAmountMax())) {
            example.and().andBetween("payAmount", query.getPayAmountMin(), query.getPayAmountMax());
        } else if (Objects.nonNull(query.getPayAmountMin())) {
            example.and().andGreaterThanOrEqualTo("payAmount", query.getPayAmountMin());
        } else if (Objects.nonNull(query.getPayAmountMax())) {
            example.and().andLessThanOrEqualTo("payAmount", query.getPayAmountMax());
        }
        if (Objects.nonNull(query.getCreateTimeStart()) && Objects.nonNull(query.getCreateTimeEnd())) {
            example.and().andBetween("createTime", query.getCreateTimeStart(), query.getCreateTimeEnd());
        }
        if (Objects.nonNull(query.getUpdateTimeStart()) && Objects.nonNull(query.getUpdateTimeEnd())) {
            example.and().andBetween("updateTime", query.getUpdateTimeStart(), query.getUpdateTimeEnd());
        }
        if (Strings.isNotEmpty(query.getKeyword())) {
            final String keyword = query.getKeyword().trim();
            example.and().andLike("orderNo", Strings.format("%{}%", keyword))
                    .orLike("outBizNo", Strings.format("%{}%", keyword))
                    .orLike("tradeNo", Strings.format("%{}%", keyword))
                    .orLike("openId", Strings.format("%{}%", keyword));
        }
        
        return example;
    }
}
